var {Options} = require('selenium-webdriver/chrome'),
    webdriver=require('selenium-webdriver/lib/webdriver'),
    {Builder,By,until}=require('selenium-webdriver'),
    config=require('./config.js'),
    text=require('./text.js'),
    https = require('https'),
    fs = require('fs'),
    driver;



;(async function main(){
    var courseLinks,lessonLinks
    driver =await new Builder().withCapabilities(
            Options.chrome().setPageLoadStrategy('none')
        ).build()
    await login()
    courseLinks=await getCourseList()
    for(var courseLink of courseLinks){
        var courseName=String(courseLink).split('/').slice(-2,-1)
    	if(fs.existsSync(config.root+courseName+'/end')){continue}
        console.log(courseLink)
        lessonLinks=await getCourseDetail(courseLink)
        for(let [idx,lessonLink] of lessonLinks.entries()){
           await getLessonDetail(lessonLink,idx)
        }
        fs.writeFile(config.root+courseName+'/end', '', function(err) {
            if (err) throw err;
        })
    }
})()

async function sleep(duration){
    return new Promise(resolve => setTimeout(resolve, duration))
}

async function login(){
    await driver.get(text.url.login)
    var ele=driver.wait(until.elementLocated(By.id('username')))
    ele.sendKeys(config.username)
    ele=await driver.findElement(By.id('password'))
    ele.sendKeys(config.password)
    driver.findElement(By.xpath('//button[contains(text(),"Log In")]')).click()
    await sleep(5e4)
}

async function getCourseList(){
    var eles,links=[],tmp
    await driver.wait(until.urlIs(text.url.dashboard),2e4)
    driver.get(text.url.courses)
    await driver.wait(until.urlIs(text.url.courses),2e4)
    eles =await driver.findElements(By.xpath('//a[contains(text(),"Watch Course")]'))
    for(ele of eles){
        tmp=await ele.getAttribute('href')
        links.push(tmp)
    }
    return links
}

async function getCourseDetail(link){
    var tmp,links=[]
    driver.get(link)
    await driver.wait(until.urlIs(link),2e4)
    eles =await driver.findElements(By.xpath('//li[@class="LessonListItem"]/a'))
    for(ele of eles){
        tmp=await ele.getAttribute('href')
        links.push(tmp)
    }
    return links
}

async function getLessonDetail(link,idx){
    console.log('link',link)
    var vtt,vttLink,
        video,videoLink,
        options,cookies,
        [courseName,lessonName]=String(link).split('/').slice(-3,-1)
    if(fs.existsSync(config.root+courseName+'/'+idx+'-'+lessonName+'.webm')){return}
    driver.get(link)
    await driver.wait(until.urlIs(link),2e4)
    //video
    await sleep(6e3)
    video =await driver.findElement(By.tagName('video'))
    videoLink=await video.getAttribute('src')
    //vtt
    vtt=await driver.findElement(By.xpath('//meta[@property="og:image"]'))
    vttLink=await vtt.getAttribute('content')
    vttLink=vttLink.split('/').slice(0,-1).join('/')+'/'+idx+'-'+lessonName+'.webvtt'
    console.log(vttLink)
    // set cookie
    options=new webdriver.Options(driver)
    cookies=await options.getCookies()
    cookies=cookies.map(v=>v['name']+'='+v['value']).join('; ')
    
    await download(videoLink,config.root+courseName+'/'+idx+'-'+lessonName+'.webm',cookies)
    //await download(vttLink,config.root+courseName+'/'+idx+'-'+lessonName+'.web_vtt',cookies)
    await sleep(2e5)
}


function download(url, dest,cookies) {
    var dir=dest.split('/').slice(0,-1).join('/')
    return new Promise((resovle,reject)=>{
        if (!fs.existsSync(dir)){
            fs.mkdirSync(dir)
        }
        if(fs.existsSync(dest)){
            resovle()
            return
        }
        var file = fs.createWriteStream(dest)
        https.get(url,{
            headers:{
		'Origin': 'https://frontendmasters.com',
		'Host': 'static.frontendmasters.com',
                'Referer': url.split('/').slice(0,-1).join('/'),
                'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36',
                'cookie':cookies
            }
        },response=>{
            response.pipe(file)
            file.on('finish', function() {
                file.close()
                resovle()
            })
        }).on('error', function(err) {
            fs.unlink(dest); 
            reject(err)
        });
    })
};
